#pragma once
#include <iostream>
#include <string>
//#include <shared_mutex>
#include <memory.h>
#include <map>

#include "dpparam.hpp"
#include "modbus.h"
#include <thread>

using namespace std;

//一组连续的dps, 一次性查询
class scan_group
{
    public:
    scan_group(){
    };
    virtual ~scan_group(){};
    void add_dp(shared_DChanneldpPtr dp);
    bool is_suitable(shared_DChanneldpPtr dp);

    vector<shared_DChanneldpPtr> m_group;
    int startReg;
    int endReg;
    int cnt;
    int slaveID;
    int func;
    int index;

};
typedef shared_ptr<scan_group> shared_scanGroupPtr;
//channel dp通道基类
class Channel
{
public:
    virtual ~Channel() {}
    virtual void  init(vector<shared_DChanneldpPtr>&){}
    virtual void  deinit(){}
    virtual int           get_channelid(){}
    virtual int start(){}
    virtual void process(const std::string& data) = 0;
    int m_slaveid;
    modbus_t *m_ctx = NULL; 
    shared_DChannelPtr m_channel_cfg; //通道参数
    int             m_workState = ECH_MB_RTU_WORK_STATE_NULL; //E_WORK_STATE
};

typedef std::shared_ptr<Channel> shared_ChannelPtr;

//Channel_modbus_rtu 继承Channel
class Channel_modbus_rtu : public Channel
{
public:
    Channel_modbus_rtu(shared_DChannelPtr dp);
    virtual void  init(vector<shared_DChanneldpPtr>& dps);
    virtual void  deinit(){}
    void sort_dps(vector<shared_DChanneldpPtr>& dps);
    void handle_scan_dps();
    void handle_group_response(shared_scanGroupPtr grp,uint8_t *resp);
    void process(const std::string& data) {
        std::thread([=](){
           // this->handle_scan_dps();
        }).detach();
    };

    string uart_com ;
    int baudrate ;
    int stop  ;
    int oddeven ;
    int logInterval ;


    vector<shared_DChanneldpPtr> m_channel_dps;
    map<int ,vector<shared_scanGroupPtr> > m_dps_groups; //将同一个通道的dps 分成不同的扫描组 fcode->[index,scangroups]
};

//Channel_modbus_tcp 继承Channel
class Channel_modbus_tcp : public Channel
{
public:
    Channel_modbus_tcp(shared_DChannelPtr dp);
    virtual void  init(vector<shared_DChanneldpPtr>&);
    virtual void  deinit();
    void sort_dps();
    void handle_scan_dps();
    void process(const std::string& data) ;
};


//channelmgr  管理多个channel
class Channelmgr
{
public:
//初始化
    void init();
    virtual void     start();
    vector<dp_param_t> get_param();

private:
    map<int,shared_ChannelPtr>          m_channels; //chid -->channel
    vector<shared_DChanneldpPtr> m_dpsTemp;
};
